import { IDirectory, IReportTree, XCollection } from '@/ts/core';
import { ReportTreeBase } from '@/ts/core/thing/standard/reporttree';
import { XAssignTask, XAssignTaskTree } from '@/ts/base/schema';
import {
  getEmptySummary,
  ReportTaskTreeSummary,
} from '@/ts/core/work/assign/reception/status';

export interface IAssignTaskTree extends IReportTree {
  taskTreeData: XAssignTaskTree;
  subNodes: XAssignTask[] | undefined;
  /** 加载任务树状态数量 */
  loadAssignTreeSummary(rootNodeId: string): Promise<ReportTaskTreeSummary>;
  loadNodes(reload?: boolean): Promise<XAssignTask[]>;
  loadPublicNodes(
    curRootNodeId: string,
    reload?: boolean,
  ): Promise<XAssignTask[] | undefined>;
  loadSubNodes(curRootNodeId: string, reload?: boolean): Promise<XAssignTask[]>;
}

export class AssignTaskTree
  extends ReportTreeBase<XAssignTaskTree, XAssignTask>
  implements IAssignTaskTree
{
  constructor(
    _metadata: XAssignTaskTree,
    _directory: IDirectory,
    treeColl?: XCollection<XAssignTaskTree>,
    assignTaskColl?: XCollection<XAssignTask>,
  ) {
    super(_metadata, _directory, treeColl ?? _directory.resource.assignTaskTreeColl);
    this._nodeColl = assignTaskColl ?? _directory.resource.assignTaskColl;
    this.taskTreeData = _metadata;
  }

  taskTreeData: XAssignTaskTree;
  subNodes: XAssignTask[] | undefined;
  private readonly _nodeColl: XCollection<XAssignTask>;

  get nodeColl() {
    return this._nodeColl;
  }

  async loadNodes(reload: boolean): Promise<XAssignTask[]> {
    return super.loadNodes(reload);
  }

  async loadChildren(curRootNodeId: string): Promise<XAssignTask[]> {
    return super.loadChildren(curRootNodeId);
  }

  async loadAssignTreeSummary(curRootNodeId: string): Promise<ReportTaskTreeSummary> {
    let summary: ReportTaskTreeSummary = getEmptySummary();
    const promise = await this.nodeColl.loadAggregate([
      {
        match: { treeId: this.metadata.id, nodePath: { _regex_: curRootNodeId } },
      },
      {
        group: {
          key: ['taskStatus'],
          count: { _sum_: 1 },
        },
      },
      { limit: 10 },
    ]);
    for (let i = 0; i < promise.length; i++) {
      if (promise[i].taskStatus) {
        // @ts-ignore
        summary[promise[i].taskStatus] += promise[i].count;
      } else {
        summary.empty += promise[i].count;
      }
      summary.total += promise[i].count;
    }
    return summary;
  }

  async loadSubNodes(curRootNodeId: string, reload?: boolean): Promise<XAssignTask[]> {
    return super.loadNodes(reload, curRootNodeId);
  }

  async loadPublicNodes(
    curRootNodeId: string,
    reload?: boolean,
  ): Promise<XAssignTask[] | undefined> {
    if (reload || !this._subTreeLoaded) {
      const subNodes = await this.target.resource.assignTaskPublicColl.loadSpace({
        options: {
          match: {
            nodePath: { _regex_: curRootNodeId },
            treeId: this.taskTreeData.id,
          },
        },
      });
      if (subNodes && subNodes.length > 0) {
        this.subNodes = subNodes;
        this._subTreeLoaded = true;
      }
    }
    return this.subNodes;
  }
}
